﻿using System.Linq;
using JetBrains.ReSharper.Feature.Services.CodeCompletion;
using JetBrains.ReSharper.Feature.Services.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Feature.Services.CSharp.CodeCompletion.Infrastructure;
using JetBrains.ReSharper.Feature.Services.Lookup;
using JetBrains.ReSharper.Psi;
using JetBrains.ReSharper.Psi.CSharp;
using JetBrains.ReSharper.Psi.CSharp.Tree;
using JetBrains.ReSharper.Psi.Services;
using JetBrains.ReSharper.Psi.Tree;

namespace MugenMvvmToolkit.ReSharper.ViewModels.CodeCompletions
{
    [Language(typeof(CSharpLanguage))]
    public class ViewModelTypeCompletion : ItemsProviderOfSpecificContext<CSharpCodeCompletionContext>
    {
        #region Overrides of ItemsProviderOfSpecificContext<CSharpCodeCompletionContext>

        protected override AutocompletionBehaviour GetAutocompletionBehaviour(
            CSharpCodeCompletionContext specificContext)
        {
            return AutocompletionBehaviour.AutocompleteWithInsert;
        }

        protected override bool AddLookupItems(CSharpCodeCompletionContext context, GroupedItemsCollector collector)
        {
            TypeProvider typeProvider = TypeProvider.Create(context.PsiModule,
                context.BasicContext.SourceFile.ResolveContext);
            collector.Clear();
            foreach (IClass item in typeProvider.FindAllViewModels().OrderBy(@class => @class.Module.Name).ThenBy(@class => @class.ShortName))
            {
                DeclaredElementLookupItem lookupItem = context
                    .LookupItemsFactory
                    .CreateDeclaredElementLookupItem(item.ShortName, item, true);
                collector.AddAtDefaultPlace(lookupItem);
            }
            return true;
        }

        protected override bool IsAvailable(CSharpCodeCompletionContext context)
        {
            var node = TextControlToPsi.GetElement<ITreeNode>(context.BasicContext.Solution,
                context.BasicContext.TextControl);
            if (node == null || node.FindParent<ITypeofExpression>() == null)
                return false;
            return ToolkitExtensions.HasViewModelTypeRequiredAttribute(node.FindParent<ICSharpArgument>());
        }

        #endregion
    }
}